﻿// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Runtime.CompilerServices;

namespace SixLabors.ImageSharp.ColorSpaces.Companding;

/// <summary>
/// Implements the Rec. 709 companding function.
/// </summary>
/// <remarks>
/// http://en.wikipedia.org/wiki/Rec._709
/// </remarks>
public static class Rec709Companding
{
    private const float Epsilon = 1 / 0.45F;

    /// <summary>
    /// Expands a companded channel to its linear equivalent with respect to the energy.
    /// </summary>
    /// <param name="channel">The channel value.</param>
    /// <returns>The <see cref="float"/> representing the linear channel value.</returns>
    [MethodImpl(InliningOptions.ShortMethod)]
    public static float Expand(float channel)
        => channel < 0.081F ? channel / 4.5F : MathF.Pow((channel + 0.099F) / 1.099F, Epsilon);

    /// <summary>
    /// Compresses an uncompanded channel (linear) to its nonlinear equivalent.
    /// </summary>
    /// <param name="channel">The channel value.</param>
    /// <returns>The <see cref="float"/> representing the nonlinear channel value.</returns>
    [MethodImpl(InliningOptions.ShortMethod)]
    public static float Compress(float channel)
        => channel < 0.018F ? 4.5F * channel : (1.099F * MathF.Pow(channel, 0.45F)) - 0.099F;
}
